using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace Glpt.Data
{
    /// <summary>
    /// 通用数据函数类
    /// </summary>
    public class DataFuns
    {
        /// <summary>
        /// 缺省字符编码
        /// </summary>
        public static Encoding DefaultEncoding = Encoding.Default;
        /// <summary>
        /// 缺省换行符
        /// </summary>
        public static string NewLineString = Environment.NewLine;
        /// <summary>
        /// 缺省目录分隔符
        /// </summary>
        public static string DirSeparator = System.IO.Path.DirectorySeparatorChar.ToString();
        public static string ConvertFromHexString(string val)
        {
            if (val.StartsWith("0x"))
            {
                string str = "";
                for (int i = 0; i < val.Length; i += 4)
                    str += Encoding.ASCII.GetString(new byte[] { Convert.ToByte(val.Substring(i, 4), 16) });
                return str;
            }
            else
                return val;
        }
        public static string ConvertToHexString(string val)
        {
            string str = "";
            for (int i = 0; i < val.Length; i++)
            {
                string stmp = Convert.ToString(Convert.ToInt32(val[i]), 16);
                str += "0x" + (stmp.Length > 1 ? "" : "0") + stmp;
            }
            return str;
        }

        public static object ConvertValue(string val, Type fieldType)
        {
            int len = val.Length;
            if (len > 0)
            {
                if (fieldType != null && fieldType.IsValueType)
                {
                    if (fieldType.Equals(typeof(DateTime)))
                    {
                        string format = "yyyyMMdd";
                        if (len == 10) format = "yyyy-MM-dd";
                        else if (len == 14) format = "yyyyMMddHHmmss";
                        else if (len == 19) format = "yyyy-MM-dd HH:mm:ss";
                        else if (len == 23) format = "yyyy-MM-dd HH:mm:ss.fff";
                        return DateTime.ParseExact(val, format, System.Globalization.CultureInfo.InvariantCulture);
                    }
                    else
                        return double.Parse(val);
                }
                else
                    return val;
            }
            else
                return DBNull.Value;
        }
        /// <summary>
        /// 分拆参数字符串
        /// </summary>
        /// <param name="paramString">参数</param>
        /// <param name="separator">分隔符</param>
        /// <param name="trim_flag">是否要去掉前后引号</param>
        /// <returns>字符串</returns>
        public static List<string> SplitString(string paramString, char separator, bool trim_flag)
        {
            List<string> values = new List<string>();
            int ibegin = 0;
            char chr_sep = '\0';
            bool isbegin = false;
            for (int i = 0; i < paramString.Length; i++)
            {
                bool is_last = (i == paramString.Length - 1);
                char chr = paramString[i];
                if ((chr.Equals('\'') || chr.Equals('"')) && (chr_sep.Equals('\0') || chr_sep.Equals(chr)))
                {
                    isbegin = !isbegin;
                    if (chr_sep.Equals('\0') && isbegin)
                        chr_sep = chr;
                }
                if (chr.Equals(separator) && !isbegin)
                {
                    string val = paramString.Substring(ibegin, i - ibegin);
                    if (trim_flag) val = GetSplitString(val);
                    values.Add(val);
                    ibegin = i + 1;
                    chr_sep = '\0';
                }
                if (is_last)
                {
                    string val = paramString.Substring(ibegin);
                    if (trim_flag) val = GetSplitString(val);
                    values.Add(val);
                }
            }
            return values;
        }
        private static string GetSplitString(string val)
        {
            string content = val.Trim();
            if (content.Length > 1 && content.StartsWith("'") && content.EndsWith("'"))
                content = content.Substring(1, content.Length - 2).Replace("''", "'");
            if (content.Length > 1 && content.StartsWith("\"") && content.EndsWith("\""))
                content = content.Substring(1, content.Length - 2).Replace("\"\"", "\"");
            return content;
        }
        /// <summary>
        /// 分拆参数字符串
        /// </summary>
        /// <param name="paramString">参数</param>
        /// <param name="separator">分隔符</param>
        /// <returns>字符串</returns>
        public static Dictionary<string, string> SplitStringValue(string paramString, char separator)
        {
            Dictionary<string, string> values = new Dictionary<string, string>();
            List<string> str_list = SplitString(paramString, separator, false);
            foreach (string value in str_list)
            {
                if (value == null || value.Length == 0) continue;
                int idx = value.IndexOf('=');
                string key = "";
                string content = "";
                if (idx > 0)
                {
                    content = GetSplitString(value.Substring(idx + 1));
                    key = value.Substring(0, idx).Trim();
                }
                else
                    key = value.Trim();
                if (!values.ContainsKey(key))
                    values.Add(key, content);
            }
            return values;
        }

        public static DataTable GetSchemaTable(IDataReader dataReader)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ColumnName", typeof(string));
            dt.Columns.Add("ColumnOrdinal", typeof(int));
            dt.Columns.Add("ColumnSize", typeof(int)).DefaultValue = 255;
            dt.Columns.Add("NumericPrecision", typeof(short)).DefaultValue = 255;
            dt.Columns.Add("NumericScale", typeof(short)).DefaultValue = 255;
            dt.Columns.Add("IsUnique", typeof(bool)).DefaultValue = false;
            dt.Columns.Add("IsKey", typeof(bool));
            dt.Columns.Add("BaseServerName", typeof(string));
            dt.Columns.Add("BaseCatalogName", typeof(string));
            dt.Columns.Add("BaseColumnName", typeof(string));
            dt.Columns.Add("BaseSchemaName", typeof(string));
            dt.Columns.Add("BaseTableName", typeof(string));
            dt.Columns.Add("DataType", typeof(System.Type));
            dt.Columns.Add("AllowDBNull", typeof(bool)).DefaultValue = true;
            dt.Columns.Add("ProviderType", typeof(int)).DefaultValue = 22;
            dt.Columns.Add("IsAliased", typeof(bool));
            dt.Columns.Add("IsExpression", typeof(bool));
            dt.Columns.Add("IsIdentity", typeof(bool)).DefaultValue = false;
            dt.Columns.Add("IsAutoIncrement", typeof(bool)).DefaultValue = false;
            dt.Columns.Add("IsRowVersion", typeof(bool)).DefaultValue = false;
            dt.Columns.Add("IsHidden", typeof(bool));
            dt.Columns.Add("IsLong", typeof(bool)).DefaultValue = false;
            dt.Columns.Add("IsReadOnly", typeof(bool)).DefaultValue = false;
            dt.Columns.Add("ProviderSpecificDataType", typeof(System.Type));
            dt.Columns.Add("XmlSchemaCollectionDatabase", typeof(string));
            dt.Columns.Add("XmlSchemaCollectionOwningSchema", typeof(string));
            dt.Columns.Add("XmlSchemaCollectionName", typeof(string));
            dt.Columns.Add("UdtAssemblyQualifiedName", typeof(string)).DefaultValue = 22;
            dt.Columns.Add("NonVersionedProviderType", typeof(int));
            dt.Columns.Add("IsColumnSet", typeof(bool)).DefaultValue = false;
            List<string> columns = new List<string>();
            for (int i = 0; i < dataReader.FieldCount; i++)
            {
                string column_name = dataReader.GetName(i);
                if (columns.Contains(column_name))
                {
                    int iseq = 1;
                    while (dt.Columns.Contains(column_name + iseq.ToString()))
                    {
                        iseq++;
                    }
                    column_name = column_name + iseq.ToString();
                }
                DataRow dr = dt.NewRow();
                dr["ColumnName"] = column_name;
                dr["ColumnOrdinal"] = i;
                dr["BaseColumnName"] = column_name;
                dr["DataType"] = dataReader.GetFieldType(i);
                dr["ProviderSpecificDataType"] = dataReader.GetFieldType(i);
                dt.Rows.Add(dr);
                columns.Add(column_name);
            }
            return dt;
        }
    }
}
